package com.zeng.nicecore.mappinghandle;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.condition.RequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.Set;

public class MdRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
    private RequestMappingInfo.BuilderConfiguration config = new RequestMappingInfo.BuilderConfiguration();

    private AnnotatedElement element = null;


    @Value("#{'com.zeng.sys,${zeng.sys.auto-mapping:com.zeng.sys}'.split(',')}")
    private Set<String> autoMappingPackage;
    @Override
    public void afterPropertiesSet() {
        this.config = new RequestMappingInfo.BuilderConfiguration();
        this.config.setUrlPathHelper(getUrlPathHelper());
        this.config.setPathMatcher(getPathMatcher());
        this.config.setSuffixPatternMatch(true);
        this.config.setTrailingSlashMatch(true);
        this.config.setRegisteredSuffixPatternMatch(false);
        this.config.setContentNegotiationManager(getContentNegotiationManager());

        super.afterPropertiesSet();
    }

    @Override
    protected RequestMappingInfo createRequestMappingInfo(RequestMapping requestMapping, RequestCondition<?> customCondition) {
        String[] paths = null;
        if (requestMapping.path().length < 1) {
            if (element instanceof Method) {
                Method m = (Method) element;
                for (String s : autoMappingPackage) {
                    if (m.getDeclaringClass().getPackage().getName().contains(s)) {
                        paths = new String[]{m.getName()};
                        break;
                    }
                }
            } else if (element instanceof Class) {
                Class c = (Class) element;
                for (String s : autoMappingPackage) {
                    if (c.getPackage().getName().contains(s)) {
                        String[] split = c.getName().split("\\.");
                        String controllerName = split[split.length - 1];
                        char[] chars = controllerName.toCharArray();
                        chars[0] = (char) (chars[0] + 32);
                        paths = new String[]{new String(chars).replace("Controller", "")};
                        break;
                    }
                }

            }
        }
        if (paths == null) {
            paths = requestMapping.path();
        }
        RequestMappingInfo.Builder builder = RequestMappingInfo
                .paths(resolveEmbeddedValuesInPatterns(paths))
                .methods(requestMapping.method())
                .params(requestMapping.params())
                .headers(requestMapping.headers())
                .consumes(requestMapping.consumes())
                .produces(requestMapping.produces())
                .mappingName(requestMapping.name());
        if (customCondition != null) {
            builder.customCondition(customCondition);
        }
        return builder.options(this.config).build();
    }

    @Override
    protected RequestCondition<?> getCustomTypeCondition(Class<?> handlerType) {
        element = handlerType;
        return super.getCustomTypeCondition(handlerType);
    }

    @Override
    protected RequestCondition<?> getCustomMethodCondition(Method method) {
        element = method;
        return super.getCustomMethodCondition(method);
    }
}
